package com.lj.back.manage.scaffold.module.job.utils;

import cn.hutool.core.bean.BeanUtil;
import com.lj.back.manage.scaffold.common.constant.Constant;
import com.lj.back.manage.scaffold.common.enums.StatusEnum;
import com.lj.back.manage.scaffold.common.util.Assert;
import com.lj.back.manage.scaffold.common.util.SpringContextUtils;
import com.lj.back.manage.scaffold.module.job.DO.ScheduleJobLogDO;
import com.lj.back.manage.scaffold.module.job.DTO.ScheduleJobDTO;
import com.lj.back.manage.scaffold.module.job.constant.JobConstant;
import com.lj.back.manage.scaffold.module.job.service.ScheduleJobLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 定时任务
 * @author lv
 */
@Slf4j
public class ScheduleJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context){
        ScheduleJobDTO scheduleJob = (ScheduleJobDTO) context.getMergedJobDataMap()
        		.get(JobConstant.JOB_PARAM_KEY);
        //获取spring bean
        ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService) SpringContextUtils.getBean(ScheduleJobLogService.class);
        //数据库保存执行记录
        ScheduleJobLogDO scheduleJobLogDO = new ScheduleJobLogDO();
        BeanUtil.copyProperties(scheduleJob,scheduleJobLogDO,CopyOptionsUtil.getJobAndJobLogInterconversionCopyOptions());
        scheduleJobLogDO.setCreateTime(LocalDateTime.now());
        //任务开始时间
        long startTime = System.currentTimeMillis();
        try {
            //执行任务
        	log.info("任务准备执行，任务ID：" + scheduleJob.getId());
            String beanMethodName = scheduleJob.getBean();
            Assert.assertIsTrue(!beanMethodName.contains(Constant.SEPARATOR_BEAN_NAME),"定时任务bean名称不合法");
        	String beanName = beanMethodName.substring(0,beanMethodName.indexOf(Constant.SEPARATOR_BEAN_NAME));
        	String methodName = beanMethodName.substring(beanMethodName.indexOf(Constant.SEPARATOR_BEAN_NAME)+1);
            Class<?> aClass = Class.forName(beanName);
            Method method = aClass.getDeclaredMethod(methodName);
            method.setAccessible(true);
            Object bean = SpringContextUtils.getBean(aClass);
            if (bean != null){
                method.invoke(bean);
            }else {
                method.invoke(aClass.newInstance());
            }
            scheduleJobLogDO.setStatus(StatusEnum.SUCCESS.getCode());
		} catch (Throwable throwable) {
			log.error("任务执行失败，任务ID：" + scheduleJob.getId(), throwable);
            scheduleJobLogDO.setStatus(StatusEnum.FAIL.getCode());
            scheduleJobLogDO.setError(StringUtils.substring(throwable.toString(), 0, 2000));
		}finally {
            //任务执行总时长
            long times = System.currentTimeMillis() - startTime;
            scheduleJobLogDO.setTimes((int)times);
			scheduleJobLogService.save(scheduleJobLogDO);
		}
    }
}
